﻿using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using CloudShot.Editor;

namespace CloudShot.Utils
{
  public static class RectangleUtils
  {
    public static Rectangle GetNormalizedRectangle(int x1, int y1, int x2, int y2)
    {
      if (x2 < x1)
      {
        int tmp = x2;
        x2 = x1;
        x1 = tmp;
      }

      if (y2 < y1)
      {
        int tmp = y2;
        y2 = y1;
        y1 = tmp;
      }

      return new Rectangle(x1, y1, x2 - x1, y2 - y1);
    }

    public static Rectangle GetNormalizedRectangle(Point p1, Point p2)
    {
      return GetNormalizedRectangle(p1.X, p1.Y, p2.X, p2.Y);
    }

    public static Rectangle GetNormalizedRectangle(this Rectangle r)
    {
      return GetNormalizedRectangle(r.X, r.Y, r.X + r.Width, r.Y + r.Height);
    }

    /// <summary>
    /// Applies <paramref name="padding"/> to the <paramref name="rectangle"/> and returns new rectangle.
    /// </summary>
    /// <param name="rectangle">A rectangle.</param>
    /// <param name="padding">A padding for rectangle.</param>
    /// <returns>The rectangle with applied padding.</returns>
    public static Rectangle ApplyPadding(this Rectangle rectangle, Padding padding)
    {
      rectangle.X += padding.Left;
      rectangle.Y += padding.Top;
      rectangle.Width -= padding.Horizontal;
      rectangle.Height -= padding.Vertical;

      return rectangle;
    }

    public static Rectangle UnionRectangles(this IEnumerable<Rectangle> rectangles)
    {
      Rectangle result = Rectangle.Empty;
      bool isFirst = true;

      foreach (var rectangle in rectangles)
      {
        if (isFirst)
        {
          result = rectangle;
          isFirst = false;
        }
        else
        {
          result = Rectangle.Union(result, rectangle);
        }
      }

      return result;
    }

    public static Rectangle ExtendToRectangle(this Point location, int diameter)
    {
      int radius = diameter / 2;
      return new Rectangle(location.X - radius, location.Y - radius, diameter, diameter);
    }

    public static Rectangle AdjustMinimalRect(this Rectangle currentRect, int defaultWidth, int defaultHeight)
    {
      Rectangle adjustedRect = currentRect.GetNormalizedRectangle();

      if (adjustedRect.Width < EditorTheme.MinimumFigureSize && adjustedRect.Height < EditorTheme.MinimumFigureSize)
      {
        adjustedRect = new Rectangle(adjustedRect.X, adjustedRect.Y, defaultWidth, defaultHeight);
      }
      else if (adjustedRect.Width < 1)
      {
        adjustedRect.Width = 1;
      }
      else if (adjustedRect.Height < 1)
      {
        adjustedRect.Height = 1;
      }

      return adjustedRect;
    }

    public static Point GetPointByHandle(this Rectangle rectangle, int handleNumber)
    {
      int xCenter = rectangle.X + rectangle.Width / 2;
      int yCenter = rectangle.Y + rectangle.Height / 2;
      int x = rectangle.X;
      int y = rectangle.Y;

      switch (handleNumber)
      {
        case VertexType.LeftTop:
          x = rectangle.X;
          y = rectangle.Y;
          break;
        case VertexType.Top:
          x = xCenter;
          y = rectangle.Y;
          break;
        case VertexType.RightTop:
          x = rectangle.Right;
          y = rectangle.Y;
          break;
        case VertexType.Right:
          x = rectangle.Right;
          y = yCenter;
          break;
        case VertexType.RightBottom:
          x = rectangle.Right;
          y = rectangle.Bottom;
          break;
        case VertexType.Bottom:
          x = xCenter;
          y = rectangle.Bottom;
          break;
        case VertexType.LeftBottom:
          x = rectangle.X;
          y = rectangle.Bottom;
          break;
        case VertexType.Left:
          x = rectangle.X;
          y = yCenter;
          break;
        case VertexType.Center:
          x = xCenter;
          y = yCenter;
          break;
      }

      return new Point(x, y);
    }

    internal static Point FitControlToRectangle(Size controlSize, Rectangle boundingRectangle, Point controlLocation)
    {
      if (!boundingRectangle.IsEmpty)
      {
        if (controlLocation.Y < boundingRectangle.Top)
        {
          controlLocation.Y = boundingRectangle.Top;
        }

        if (controlLocation.Y > boundingRectangle.Bottom - controlSize.Height)
        {
          controlLocation.Y = boundingRectangle.Bottom - controlSize.Height;
        }

        if (controlLocation.X + controlSize.Width > boundingRectangle.Right)
        {
          controlLocation.X = boundingRectangle.Right - controlSize.Width;
        }

        if (controlLocation.X < boundingRectangle.Left)
        {
          controlLocation.X = boundingRectangle.Left;
        }
      }
      return controlLocation;
    }

  }
}